package com.cbianc.creation.builder


/*-*- coding:utf-8 -*-
模式的应用场景
建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说，如果创建简单对象，通常都是使用工厂模式进行创建，而如果创建复杂对象，就可以考虑使用建造者模式。

当需要创建的产品具备复杂创建过程时，可以抽取出共性创建过程，然后交由具体实现类自定义创建流程，使得同样的创建行为可以生产出不同的产品，分离了创建与表示，使创建产品的灵活性大大增加。

    建造者模式主要适用于以下应用场景：
        相同的方法，不同的执行顺序，产生不同的结果。
        多个部件或零件，都可以装配到一个对象中，但是产生的结果又不相同。
        产品类非常复杂，或者产品类中不同的调用顺序产生不同的作用。
        初始化一个对象特别复杂，参数多，而且很多参数都具有默认值。
    建造者模式和工厂模式的区别
        通过前面的学习，我们已经了解了建造者模式，那么它和工厂模式有什么区别呢？
        建造者模式更加注重方法的调用顺序，工厂模式注重创建对象。
        创建对象的力度不同，建造者模式创建复杂的对象，由各种复杂的部件组成，工厂模式创建出来的对象都一样
        关注重点不一样，工厂模式只需要把对象创建出来就可以了，而建造者模式不仅要创建出对象，还要知道对象由哪些部件组成。
        建造者模式根据建造过程中的顺序不一样，最终对象部件组成也不一样。
    模式的扩展
        建造者（Builder）模式在应用过程中可以根据需要改变，如果创建的产品种类只有一种，只需要一个具体建造者，这时可以省略掉抽象建造者，甚至可以省略掉指挥者角色。
 */
abstract class Builder {
    //创建产品对象
    protected var product = Product()
    abstract fun buildPartA()
    abstract fun buildPartB()
    abstract fun buildPartC()

    //返回产品对象
    fun getResult(): Product {
        return product
    }
}
/*
*  具体建造者：实现了抽象建造者接口。*/

class ConcreteBuilder : Builder() {
    override fun buildPartA() {
        product.partA = "建造 PartA"
    }

    override fun buildPartB() {
        product.partB = "建造 PartB"
    }

    override fun buildPartC() {
        product.partC = "建造 PartC"
    }
}

/*指挥者：调用建造者中的方法完成复杂对象的创建。*/
internal class Director(private val builder: Builder) {
    //产品构建与组装方法
    fun construct(): Product {
        builder.buildPartA()
        builder.buildPartB()
        builder.buildPartC()
        return builder.getResult()
    }
}

fun main() {
    val builder: Builder = ConcreteBuilder()
    val director = Director(builder)
    val product = director.construct()
    product.show()

}